﻿//#include <iostream>
//using namespace std;
//int main()
//{
//	// 隐式类型转换
//	// 隐式类型转换主要发⽣在整形和整形之间，整形和浮点数之间，浮点数和浮点数之间
//	int i = 1;
//	double d = i;
//	printf("%d, %.2f\n", i, d);
//
//    // 显⽰的强制类型转换
//	// 强制类型转换主要发⽣在指针和整形之间，指针和指针之间
//	int* p = &i;
//	int address = (int)p;
//	printf("%p, %d\n", p, address);
//	// malloc返回值是void*，被强转成int*
//	int* ptr = (int*)malloc(8);
//
//	// 编译报错：类型强制转换: ⽆法从“int *”转换为“double”
//	// 指针是地址的编号，也是⼀种整数，所以可以和整形互相转换
//	// 但是指针和浮点数毫⽆关联，强转也是不⽀持的
//	 d = (double)p;
//	return 0;
//}

//#include <iostream>
//using namespace std;
//// 内置类型和⾃定义类型之间
//// 1、⾃定义类型 = 内置类型 ->构造函数⽀持
//// 2、内置类型 = ⾃定义类型 ->operator 内置类型 ⽀持
//class A
//{
//public:
//	//构造函数加上explicit就不⽀持隐式类型转换了,只支持显式强制类型转换
//	//explicit A(int a)
//	A(int a)
//		:_a1(a)
//		, _a2(a)
//	{
//		cout << _a1 << " " << _a2 << endl;
//	}
//	A(int a1, int a2)
//		:_a1(a1)
//		, _a2(a2)
//	{
//		cout << _a1 << " " << _a2 << endl;
//	}
//	//加上explicit就不⽀持隐式类型转换了,只支持显式强制类型转换
//	//explicit operator int()
//	//operator int()表示将内置类型转换成int类型
//	operator int() const
//	{
//		cout << _a1 + _a2 << endl;
//		return _a1 + _a2;
//	}
//private:
//	int _a1 = 1;
//	int _a2 = 1;
//};
//
//class B
//{
//public:
//	B(int b)
//		:_b1(b)
//	{}
//	// ⽀持A类型对象转换为B类型对象
//	B(const A& aa)
//		:_b1(aa)
//	{
//		cout << _b1 << endl;
//	}
//private:
//	int _b1 = 1;
//};
//
//int main()
//{
//	//单参数内置类型转换内置类型
//	A a1 = 1;
//	A aa1 = (A)2;
//
//	//多参数内置类型转换内置类型
//	A a2 = { 1,2 };
//
//	//自定义类型转换内置类型
//	int i1 = a1;
//	int ii1 = (int)a1;
//
//	//自定义类型转换其他的自定义类型
//	B b1 = a2;
//	B bb1 = 2;
//
//	return 0;
//}

//#include <iostream>
//using namespace std;
//void insert(size_t pos, char ch)
//{
//	// 这⾥当pos==0时，就会引发由于隐式类型转换
//	// end跟pos⽐较时，提升为size_t导致判断结束逻辑出现问题
//	// 在数组中访问挪动数据就会出现越界，经典的类型安全问题
//	int end = 10;
//	while (end >= pos)
//	{
//		// ...
//		cout << end << endl;
//		--end;
//	}
//}
//int main()
//{
//	insert(5, 'x');
//	//insert(0, 'x');
//	// 这⾥会本质已经出现了越界访问，只是越界不⼀定能被检查出来
//	const int y = 0;
//	int* p2 = (int*)&y;
//	(*p2) = 1;
//	// 这⾥打印的结果是1和0，也是因为我们类型转换去掉了const属性
//	// 但是编译器认为y是const的，不会被改变，所以会优化编译时放到
//	// 寄存器或者直接替换y为0导致的
//	cout << *p2 << endl;
//	cout << y << endl;
//	return 0;
//}

//#include <iostream>
//using namespace std;
//class A
//{
//public:
//	virtual void f()
//	{}
//	int _a = 1;
//};
//
//class B : public A
//{
//public:
//	int _b = 2;
//};
//
//void fun1(A* pa)
//{
//	// 指向⽗类转换时有⻛险的，后续访问存在越界访问的⻛险
//	// 指向⼦类转换时安全
//	B* pb1 = (B*)pa;
//	cout << "pb1:" << pb1 << endl;
//	cout << pb1->_a << endl;
//	cout << pb1->_b << endl;
//	pb1->_a++;
//	pb1->_b++;
//	cout << pb1->_a << endl;
//	cout << pb1->_b << endl;
//}
//
//void fun2(A* pa)
//{
//	// dynamic_cast会先检查基类对象的指针或者引用是否指向⼦类对象，能成功则转换，
//	// (指向⽗类对象)转换失败则返回nullptr
//	B* pb1 = dynamic_cast<B*>(pa);
//	if (pb1)
//	{
//		cout << "pb1:" << pb1 << endl;
//		cout << pb1->_a << endl;
//		cout << pb1->_b << endl;
//		pb1->_a++;
//		pb1->_b++;
//		cout << pb1->_a << endl;
//		cout << pb1->_b << endl;
//	}
//	else
//	{
//		cout << "转换失败" << endl;
//	}
//}
//
//void fun3(A& pa)
//{
//	// 转换失败，则抛出bad_cast异常
//	try {
//		B& pb1 = dynamic_cast<B&>(pa);
//		cout << "转换成功" << endl;
//	}
//	catch (const exception& e)
//	{
//		cout << e.what() << endl;
//	}
//}
//
//int main()
//{
//	// static_cast：对应隐式类型转换 -- 数据的解释意义没有改变
//	double d = 12.34;
//	int a = static_cast<int>(d);
//	cout << a << endl;
//	int&& ref = static_cast<int&&>(a);
//
//	// reinterpret_cast：对应强制类型转换 -- 数据的解释意义已经发⽣改变
//	int* p1 = reinterpret_cast<int*>(a);
//
//	// const_cast：对应强制类型转换中有⻛险的去掉const属性
//    // 所以要注意加volatile
//	volatile const int b = 0;
//	int* p2 = const_cast<int*>(&b);
//	*p2 = 1;
//	cout << b << endl;
//	cout << *p2 << endl;
//
//	A aa;
//	B bb;
//	//fun1(&a);
//	//fun1(&b);
//	fun2(&aa);
//	fun2(&bb);
//	fun3(aa);
//	fun3(bb);
//	return 0;
//}

//#include<iostream>
//#include<string>
//#include<vector>
//#include<list>
//using namespace std;
//int main()
//{
//	int a[10];
//	int* ptr = nullptr;
//	cout << typeid(10).name() << endl;
//	cout << typeid(a).name() << endl;
//	cout << typeid(ptr).name() << endl;
//
//	cout << typeid(string).name() << endl;
//	cout << typeid(string::iterator).name() << endl;
//	cout << typeid(vector<int>).name() << endl;
//	cout << typeid(vector<int>::iterator).name() << endl;
//
//	return 0;
//}

#include<iostream>
using namespace std;
class A
{
public:
	virtual void func()
	{}
protected:
	int _a1 = 1;
};
class B : public A
{
protected:
	int _b1 = 2;
};
int main()
{
	try
	{
		B* pb = new B;
		A* pa = (A*)pb;
		if (typeid(*pb) == typeid(B))
		{
			cout << "typeid(*pb) == typeid(B)" << endl;
		}
		// 如果A和B不是继承关系，则会抛bad_typeid异常
		if (typeid(*pa) == typeid(B))
		{
			cout << "typeid(*pa) == typeid(B)" << endl;
		}
		// 这⾥pa和pb是A*和B*，不是类类型对象，他会被当做编译是求值的静态类型运算
		// 所以这⾥始终是不相等的
		if (typeid(pa) == typeid(pb))
		{
			cout << "typeid(pa) == typeid(pb)" << endl;
		}
	}
	catch (const std::exception& e)
	{
		cout << e.what() << endl;
	}

	return 0;
}
